gcc 静态编译与动态编译

您所在的位置:网站首页 linux gcc 编译命令 gcc 静态编译与动态编译

gcc 静态编译与动态编译

2024-03-29 07:00| 来源: 网络整理| 查看: 265

 gcc中的连接选项(Linker Options):

-LDirectory

-L    用于指定连接库所需要的搜索路径,后面的参数“Directory”为相对路径或绝对路径-llibrary

-l    用于指定连接库文件选项例如:-lmylib 如果存在静态库,则意味着需要连接libmylib.a;如果存在动态库,则意味着需要连接libmylib.so

-static       

-static     采用静态连接的方式连接程序 -shared      生成可共享的被其他程序连接的目标模块 gcc程序生成过程的两个阶段:

step1.编译源文件生成目标文件(*.o)gcc -c -o main.o main.cstep2.连接目标文件,生成可执行程序gcc main.o -o test               //动态连接方式生成可执行程序gcc main.o -static -o test_static     //生成静态连接的可执行程序

生成动态库:

比如:gcc -shared test.o -o libtest_d.so //将test.o文件连接,生成动态库的名称为libtest_d.so生成动态可执行文件:gcc test.o -L. -ltest_d -o test_dlib //生成动态连接的可执行程序test_dlib-L.在连接时搜索库文件的时候包含当前目录;-ltest_d连接名称为libtest_d.so的动态库。

实验步骤:

1.编写测试程序:

用vi编写say.c程序如下:#include "stdio.h"void say(){printf("Say!");}

用vi编写test.c程序如下:#include "stdio.h"void say();main(){say();}

2.静态编译:

2.1. 编译源文件生成目标文件say.o

gcc -c say.c2.2. 使用静态编译归档命令ar将目标文件编译成say.a静态库文件

ar -r say.a say.o2.3. 编译test.c文件并连接目标静态库文件say.a生成可执行程序test

gcc test.c say.a -o test (或上一步用名字libsay.a,这里用命令gcc test.c -L. -lsay -o test)2.4. 测试

file testtest: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux2.2.5, dynamically linked (uses shared libs), not stripped

ldd test       libc.so.6 => /lib/tls/libc.so.6(0x42000000)       /lib/ld-linux.so.2 =>/lib/ld-linux.so.2 (0x40000000)输出结果让我们看不到任何跟say.a这个我们自己写的静态库的关系.说明程序运行时已经不需要这个静态库了,它已经被ld链接进最终的程序了.

3.动态编译

3.1.

gcc -fPIC -shared say.c -o say.so3.2.

gcc test.c say.so -o test(如果这里用gcc test.c ./say.so -o test则把say.so的相对路径硬编码进了程序里,ldd查看可知能找到)3.3.测试

ldd test(或用gcc -shared -Wall -g say.c -olibsay_d.so;再gcc test.c -L. -lsay_d -o test;最后用ldd test查看)4.测试结果ldd test       say.so => not found       libc.so.6 => /lib/tls/libc.so.6(0x42000000)       /lib/ld-linux.so.2 =>/lib/ld-linux.so.2 (0x40000000)file testtest: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux2.2.5, dynamically linked (uses shared libs), not stripped如果不出意外的话,会出现say.so => notfound.这时的./test是不能运行的.这是因为默认动态库搜索路径还没有设置,所以找不到say.so在哪,但至少说明程序运行时是需要这个库的.===========================.so文件 搜索顺序:LD_LIBRARY_PATH变量ld.so.cache (由 ldconfig 生成)binutils 编译时候指定的 --with-lib-path 参数还有,如果要让 ldconfig 搜索到相应的 so 文件,文件名必须要是 libXXXX.so 这样的格式才行。===========================

所以想让上面动态编译的程序能够运行,可以用如下方法将当前路径“.目录”加入搜索范围,或将say.so拷贝至/lib等默认搜索路径:

exportLD_LIBRARY_PATH=. ******************************(或可直接LD_LIBRARY_PATH=1 ./test1) ******************************(或/sbin/ldconfig ./;./test)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3